home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / emula / arosdv19.lha / AROS / config / linux / graphics_driver.c next >
C/C++ Source or Header  |  1996-10-31  |  12KB  |  563 lines

  1. #include <X11/Xlib.h>
  2. #include <X11/cursorfont.h>
  3.  
  4. #define DEBUG_FreeMem 1
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <exec/memory.h>
  10. #include <clib/exec_protos.h>
  11. #include <graphics/rastport.h>
  12. #include <graphics/gfxbase.h>
  13. #include <graphics/text.h>
  14. #include <clib/graphics_protos.h>
  15. #include <clib/aros_protos.h>
  16. #include "graphics_intern.h"
  17.  
  18. #define static    /* nothing */
  19.  
  20. static Display         * sysDisplay;
  21. static int           sysScreen;
  22. static Cursor           sysCursor;
  23.  
  24. /* Table which links TextAttr with X11 font names */
  25. struct FontTable
  26. {
  27.     struct TextAttr ta;
  28.     char      * name;
  29. }
  30. AROSFontTable[] =
  31. {
  32.     { { "topaz.font",      8, FS_NORMAL, FPF_ROMFONT  }, "8x13bold" },
  33.     { { "topaz.font",     13, FS_NORMAL, FPF_ROMFONT  }, "8x13bold" },
  34.     { { "helvetica.font", 11, FS_NORMAL, FPF_DISKFONT }, "-adobe-helvetica-medium-r-normal--11-*-100-100-*-*-iso8859-1" },
  35.     { { "helvetica.font", 12, FS_NORMAL, FPF_DISKFONT }, "-adobe-helvetica-medium-r-normal--12-*-100-100-*-*-iso8859-1" },
  36.     { { "helvetica.font", 14, FS_NORMAL, FPF_DISKFONT }, "-adobe-helvetica-medium-r-normal--14-*-100-100-*-*-iso8859-1" },
  37. };
  38.  
  39. #define PEN_BITS    4
  40. #define NUM_COLORS  (1L << PEN_BITS)
  41. #define PEN_MASK    (NUM_COLORS - 1)
  42.  
  43. static const char * sysColName[NUM_COLORS] =
  44. {
  45.     "grey70",
  46.     "black",
  47.     "white",
  48.     "orange",
  49.  
  50.     "blue",
  51.     "green",
  52.     "red",
  53.     "cyan",
  54.  
  55.     "magenta",
  56.     "violet",
  57.     "brown",
  58.     "bisque",
  59.  
  60.     "lavender",
  61.     "navy",
  62.     "khaki",
  63.     "sienna",
  64. };
  65.  
  66. static long sysCMap[NUM_COLORS];
  67. static unsigned long sysPlaneMask;
  68.  
  69. struct ETextFont
  70. {
  71.     struct TextFont etf_Font;
  72.     XFontStruct     etf_XFS;
  73. };
  74.  
  75. #define ETF(tf)         ((struct ETextFont *)tf)
  76.  
  77.  
  78. int driver_init (struct GfxBase * GfxBase)
  79. {
  80.     char * displayName;
  81.     Colormap cm;
  82.     XColor xc;
  83.     XColor fg, bg;
  84.     short t;
  85.     short depth;
  86.  
  87.     if (!(displayName = getenv ("DISPLAY")) )
  88.     displayName = ":0.0";
  89.  
  90.     if (!(sysDisplay = XOpenDisplay (displayName)) )
  91.     {
  92.     fprintf (stderr, "Cannot open display %s\n", displayName);
  93.     return False;
  94.     }
  95.  
  96.     sysScreen = DefaultScreen (sysDisplay);
  97.  
  98.     depth = DisplayPlanes (sysDisplay, sysScreen);
  99.     cm = DefaultColormap (sysDisplay, sysScreen);
  100.  
  101.     sysPlaneMask = 0;
  102.  
  103.     for (t=0; t < NUM_COLORS; t++)
  104.     {
  105.     if (depth == 1)
  106.     {
  107.         sysCMap[t] = !(t & 1) ?
  108.             WhitePixel(sysDisplay, sysScreen) :
  109.             BlackPixel(sysDisplay, sysScreen);
  110.     }
  111.     else
  112.     {
  113.         if (XParseColor (sysDisplay, cm, sysColName[t], &xc))
  114.         {
  115.         if (!XAllocColor (sysDisplay, cm, &xc))
  116.         {
  117.             fprintf (stderr, "Couldn't allocate color %s\n",
  118.                 sysColName[t]);
  119.             sysCMap[t] = !(t & 1) ?
  120.                 WhitePixel(sysDisplay, sysScreen) :
  121.                 BlackPixel(sysDisplay, sysScreen);
  122.         }
  123.  
  124.         sysCMap[t] = xc.pixel;
  125.  
  126.         if (t == 0)
  127.             bg = xc;
  128.         else if (t == 1)
  129.             fg = xc;
  130.         }
  131.         else
  132.         {
  133.         fprintf (stderr, "Couldn't get color %s\n", sysColName[t]);
  134.         }
  135.     }
  136.  
  137.     sysPlaneMask |= sysCMap[t];
  138.     }
  139.  
  140.     sysCursor = XCreateFontCursor (sysDisplay, XC_top_left_arrow);
  141.     XRecolorCursor (sysDisplay, sysCursor, &fg, &bg);
  142.  
  143.     return True;
  144. }
  145.  
  146. int driver_open (struct GfxBase * GfxBase)
  147. {
  148.     return True;
  149. }
  150.  
  151. void driver_close (struct GfxBase * GfxBase)
  152. {
  153.     return;
  154. }
  155.  
  156. void driver_expunge (struct GfxBase * GfxBase)
  157. {
  158.     return;
  159. }
  160.  
  161. GC GetGC (struct RastPort * rp)
  162. {
  163.     return (GC) rp->longreserved[0];
  164. }
  165.  
  166. int GetXWindow (struct RastPort * rp)
  167. {
  168.     return (int) rp->longreserved[1];
  169. }
  170.  
  171. void SetGC (struct RastPort * rp, GC gc)
  172. {
  173.     rp->longreserved[0] = (IPTR)gc;
  174. }
  175.  
  176. void SetXWindow (struct RastPort * rp, int win)
  177. {
  178.     rp->longreserved[1] = (IPTR)win;
  179. }
  180.  
  181. Display * GetSysDisplay (void)
  182. {
  183.     return sysDisplay;
  184. }
  185.  
  186. int GetSysScreen (void)
  187. {
  188.     return sysScreen;
  189. }
  190.  
  191. void driver_SetABPenDrMd (struct RastPort * rp, ULONG apen, ULONG bpen,
  192.     ULONG drmd, struct GfxBase * GfxBase)
  193. {
  194.     apen &= PEN_MASK;
  195.     bpen &= PEN_MASK;
  196.  
  197.     XSetForeground (sysDisplay, GetGC (rp), sysCMap[apen]);
  198.     XSetBackground (sysDisplay, GetGC (rp), sysCMap[bpen]);
  199.  
  200.     if (drmd & COMPLEMENT)
  201.     XSetFunction (sysDisplay, GetGC(rp), GXxor);
  202.     else
  203.     XSetFunction (sysDisplay, GetGC(rp), GXcopy);
  204. }
  205.  
  206. void driver_SetAPen (struct RastPort * rp, ULONG pen,
  207.             struct GfxBase * GfxBase)
  208. {
  209.     pen &= PEN_MASK;
  210.  
  211.     XSetForeground (sysDisplay, GetGC (rp), sysCMap[pen]);
  212. }
  213.  
  214. void driver_SetBPen (struct RastPort * rp, ULONG pen,
  215.             struct GfxBase * GfxBase)
  216. {
  217.     pen &= PEN_MASK;
  218.  
  219.     XSetBackground (sysDisplay, GetGC (rp), sysCMap[pen]);
  220. }
  221.  
  222. void driver_SetOutlinePen (struct RastPort * rp, ULONG pen,
  223.             struct GfxBase * GfxBase)
  224. {
  225. }
  226.  
  227. void driver_SetDrMd (struct RastPort * rp, ULONG mode,
  228.             struct GfxBase * GfxBase)
  229. {
  230.     if (mode & COMPLEMENT)
  231.     XSetFunction (sysDisplay, GetGC(rp), GXxor);
  232.     else
  233.     XSetFunction (sysDisplay, GetGC(rp), GXcopy);
  234. }
  235.  
  236. void driver_EraseRect (struct RastPort * rp, LONG x1, LONG y1, LONG x2, LONG y2,
  237.             struct GfxBase * GfxBase)
  238. {
  239.     XClearArea (sysDisplay, GetXWindow (rp),
  240.         x1, y1, x2-x1+1, y2-y1+1, False);
  241. }
  242.  
  243. void driver_RectFill (struct RastPort * rp, LONG x1, LONG y1, LONG x2, LONG y2,
  244.             struct GfxBase * GfxBase)
  245. {
  246.     if (rp->DrawMode & COMPLEMENT)
  247.     {
  248.     ULONG pen;
  249.  
  250.     pen = ((ULONG)(rp->FgPen)) & PEN_MASK;
  251.  
  252.     XSetForeground (sysDisplay, GetGC (rp), sysPlaneMask);
  253.  
  254.     XFillRectangle (sysDisplay, GetXWindow (rp), GetGC (rp),
  255.         x1, y1, x2-x1+1, y2-y1+1);
  256.  
  257.     XSetForeground (sysDisplay, GetGC (rp), sysCMap[pen]);
  258.     }
  259.     else
  260.     XFillRectangle (sysDisplay, GetXWindow (rp), GetGC (rp),
  261.         x1, y1, x2-x1+1, y2-y1+1);
  262. }
  263.  
  264. #define SWAP(a,b)       { a ^= b; b ^= a; a ^= b; }
  265. #define ABS(x)          ((x) < 0 ? -(x) : (x))
  266.  
  267. void driver_ScrollRaster (struct RastPort * rp, LONG dx, LONG dy,
  268.     LONG x1, LONG y1, LONG x2, LONG y2, struct GfxBase * GfxBase)
  269. {
  270.     LONG w, h, x3, y3, x4, y4, _dx_, _dy_;
  271.     ULONG apen = GetAPen (rp);
  272.  
  273.     if (!dx && !dy) return;
  274.  
  275.     if (x2 < x1) SWAP (x1,x2)
  276.     if (y2 < y1) SWAP (y1,y2)
  277.  
  278.     _dx_ = ABS(dx);
  279.     _dy_ = ABS(dy);
  280.  
  281.     x3 = x1 + _dx_;
  282.     y3 = y1 + _dy_;
  283.  
  284.     x4 = x2 - _dx_ +1;
  285.     y4 = y2 - _dy_ +1;
  286.  
  287.     w = x2 - x3 +1;
  288.     h = y2 - y3 +1;
  289.  
  290.     SetAPen (rp, rp->BgPen);
  291.  
  292.     if (dx <= 0) {
  293.     if (dy <= 0) {
  294.         XCopyArea (sysDisplay,GetXWindow(rp),GetXWindow(rp),GetGC(rp),
  295.             x1, y1, w, h, x3, y3);
  296.  
  297.         if (_dy_) XClearArea (sysDisplay,GetXWindow(rp),
  298.             x1, y1, w+_dx_, _dy_, FALSE);
  299.  
  300.         if (_dx_) XClearArea (sysDisplay,GetXWindow(rp),
  301.             x1, y1, _dx_, h, FALSE);
  302.  
  303.     } else { /* dy > 0 */
  304.         XCopyArea (sysDisplay,GetXWindow(rp),GetXWindow(rp),GetGC(rp),
  305.             x1, y3, w, h, x3, y1);
  306.  
  307.         XClearArea (sysDisplay,GetXWindow(rp),
  308.             x1, y4, w+_dx_, _dy_, FALSE);
  309.  
  310.         if (_dx_) XClearArea (sysDisplay,GetXWindow(rp),
  311.             x1, y1, _dx_, h, FALSE);
  312.     }
  313.     } else { /* dx > 0 */
  314.     if (dy <= 0) {
  315.         XCopyArea (sysDisplay,GetXWindow(rp),GetXWindow(rp),GetGC(rp),
  316.             x3, y1, w, h, x1, y3);
  317.  
  318.         if (_dy_) XClearArea (sysDisplay,GetXWindow(rp),
  319.             x1, y1, w+_dx_, _dy_, FALSE);
  320.  
  321.         XClearArea (sysDisplay,GetXWindow(rp),
  322.             x4, y3, _dx_, h, FALSE);
  323.     } else { /* dy > 0 */
  324.         XCopyArea (sysDisplay,GetXWindow(rp),GetXWindow(rp),GetGC(rp),
  325.             x3, y3, w, h, x1, y1);
  326.  
  327.         XClearArea (sysDisplay,GetXWindow(rp),
  328.             x1, y4, w+_dx_, _dy_, FALSE);
  329.  
  330.         XClearArea (sysDisplay,GetXWindow(rp),
  331.             x4, y1, _dx_, h, FALSE);
  332.     }
  333.     }
  334.  
  335.     SetAPen (rp, apen);
  336. }
  337.  
  338. void driver_DrawEllipse (struct RastPort * rp, LONG x, LONG y, LONG rx, LONG ry,
  339.         struct GfxBase * GfxBase)
  340. {
  341.     XDrawArc (sysDisplay, GetXWindow(rp), GetGC(rp),
  342.         x-rx, y-ry, rx*2, ry*2,
  343.         0, 360*64);
  344. }
  345.  
  346. void driver_Text (struct RastPort * rp, STRPTR string, LONG len,
  347.         struct GfxBase * GfxBase)
  348. {
  349.     if (rp->DrawMode & JAM2)
  350.     XDrawImageString (sysDisplay, GetXWindow(rp), GetGC(rp), rp->cp_x,
  351.         rp->cp_y, string, len);
  352.     else
  353.     XDrawString (sysDisplay, GetXWindow(rp), GetGC(rp), rp->cp_x,
  354.         rp->cp_y, string, len);
  355.  
  356.     rp->cp_x += TextLength (rp, string, len);
  357. }
  358.  
  359. WORD driver_TextLength (struct RastPort * rp, STRPTR string, ULONG len,
  360.             struct GfxBase * GfxBase)
  361. {
  362.     struct ETextFont * etf;
  363.  
  364.     etf = (struct ETextFont *)rp->Font;
  365.  
  366.     return XTextWidth (&etf->etf_XFS, string, len);
  367. }
  368.  
  369. void driver_Move (struct RastPort * rp, LONG x, LONG y,
  370.             struct GfxBase * GfxBase)
  371. {
  372.     return;
  373. }
  374.  
  375. void driver_Draw (struct RastPort * rp, LONG x, LONG y,
  376.             struct GfxBase * GfxBase)
  377. {
  378.     XDrawLine (sysDisplay, GetXWindow(rp), GetGC(rp),
  379.         rp->cp_x, rp->cp_y,
  380.         x, y);
  381. }
  382.  
  383. ULONG driver_ReadPixel (struct RastPort * rp, LONG x, LONG y,
  384.             struct GfxBase * GfxBase)
  385. {
  386.     return 0;
  387. }
  388.  
  389. LONG driver_WritePixel (struct RastPort * rp, LONG x, LONG y,
  390.             struct GfxBase * GfxBase)
  391. {
  392.     XDrawPoint (sysDisplay, GetXWindow(rp), GetGC(rp),
  393.         x, y);
  394.  
  395.     return 0;
  396. }
  397.  
  398. void driver_PolyDraw (struct RastPort * rp, LONG count, WORD * coords,
  399.             struct GfxBase * GfxBase)
  400. {
  401.     XDrawLines (sysDisplay, GetXWindow(rp), GetGC(rp),
  402.         (XPoint *)coords, count,
  403.         CoordModeOrigin
  404.     );
  405. }
  406.  
  407. void driver_SetRast (struct RastPort * rp, ULONG color,
  408.             struct GfxBase * GfxBase)
  409. {
  410.     XClearArea (sysDisplay, GetXWindow(rp),
  411.         0, 0,
  412.         1000, 1000,
  413.         FALSE);
  414. }
  415.  
  416. void driver_SetFont (struct RastPort * rp, struct TextFont * font,
  417.             struct GfxBase * GfxBase)
  418. {
  419.     if (GetGC(rp))
  420.     XSetFont (sysDisplay, GetGC(rp), ETF(font)->etf_XFS.fid);
  421.  
  422.     rp->Font       = font;
  423.     rp->TxWidth    = ETF(font)->etf_Font.tf_XSize;
  424.     rp->TxHeight   = ETF(font)->etf_Font.tf_YSize;
  425.     rp->TxBaseline = ETF(font)->etf_Font.tf_Baseline;
  426. }
  427.  
  428. struct TextFont * driver_OpenFont (struct TextAttr * ta,
  429.     struct GfxBase * GfxBase)
  430. {
  431.     struct ETextFont * tf;
  432.     XFontStruct      * xfs;
  433.     int t;
  434.     char * name;
  435.  
  436.     if (!ta->ta_Name)
  437.     return NULL;
  438.  
  439.     if (!(tf = AllocMem (sizeof (struct ETextFont), MEMF_ANY)) )
  440.     return (NULL);
  441.  
  442.     xfs = NULL;
  443.  
  444.     for (t=0; t<sizeof(AROSFontTable)/sizeof(AROSFontTable[0]); t++)
  445.     {
  446.     if (AROSFontTable[t].ta.ta_YSize == ta->ta_YSize
  447.         && !strcasecmp (AROSFontTable[t].ta.ta_Name, ta->ta_Name)
  448.     )
  449.     {
  450.         xfs = XLoadQueryFont (sysDisplay, AROSFontTable[t].name);
  451.         break;
  452.     }
  453.     }
  454.  
  455.     if (!xfs)
  456.     {
  457.     FreeMem (tf, sizeof (struct ETextFont));
  458.     return (NULL);
  459.     }
  460.  
  461.     tf->etf_XFS = *xfs;
  462.  
  463.     t = strlen (ta->ta_Name);
  464.  
  465.     name = AllocVec (t+1, MEMF_ANY);
  466.  
  467.     if (name)
  468.     strcpy (name, ta->ta_Name);
  469.     else
  470.     {
  471.     FreeMem (tf, sizeof (struct ETextFont));
  472.     return (NULL);
  473.     }
  474.  
  475.     tf->etf_Font.tf_Message.mn_Node.ln_Name = name;
  476.     tf->etf_Font.tf_YSize = tf->etf_XFS.max_bounds.ascent +
  477.             tf->etf_XFS.max_bounds.descent;
  478.     tf->etf_Font.tf_XSize = tf->etf_XFS.max_bounds.rbearing -
  479.             tf->etf_XFS.min_bounds.lbearing;
  480.     tf->etf_Font.tf_Baseline = tf->etf_XFS.ascent;
  481.     tf->etf_Font.tf_LoChar = tf->etf_XFS.min_char_or_byte2;
  482.     tf->etf_Font.tf_HiChar = tf->etf_XFS.max_char_or_byte2;
  483.  
  484.     if (!tf->etf_Font.tf_XSize || !tf->etf_Font.tf_YSize)
  485.     {
  486.     XUnloadFont (sysDisplay, tf->etf_XFS.fid);
  487.     FreeMem (tf, sizeof (struct ETextFont));
  488.     return (NULL);
  489.     }
  490.  
  491.     tf->etf_Font.tf_Accessors ++;
  492.  
  493.     return (struct TextFont *)tf;
  494. }
  495.  
  496. void driver_CloseFont (struct TextFont * tf, struct GfxBase * GfxBase)
  497. {
  498.     if (!ETF(tf)->etf_Font.tf_Accessors)
  499.     {
  500.     XUnloadFont (sysDisplay, ETF(tf)->etf_XFS.fid);
  501.     FreeVec (ETF(tf)->etf_Font.tf_Message.mn_Node.ln_Name);
  502.     FreeMem (tf, sizeof (struct ETextFont));
  503.     }
  504.     else
  505.     ETF(tf)->etf_Font.tf_Accessors --;
  506. }
  507.  
  508. int driver_InitRastPort (struct RastPort * rp, struct GfxBase * GfxBase)
  509. {
  510.     XGCValues gcval;
  511.     GC gc;
  512.  
  513.     gcval.plane_mask = sysPlaneMask;
  514.     gcval.graphics_exposures = True;
  515.  
  516.     gc = XCreateGC (sysDisplay
  517.     , DefaultRootWindow (sysDisplay)
  518.     , GCPlaneMask
  519.         | GCGraphicsExposures
  520.     , &gcval
  521.     );
  522.  
  523.     if (!gc)
  524.     return FALSE;
  525.  
  526.     SetGC (rp, gc);
  527.  
  528.     return TRUE;
  529. }
  530.  
  531. int driver_CloneRastPort (struct RastPort * newRP, struct RastPort * oldRP,
  532.             struct GfxBase * GfxBase)
  533. {
  534.     GC gc;
  535.  
  536.     gc = XCreateGC (sysDisplay
  537.     , GetXWindow (oldRP)
  538.     , 0L
  539.     , NULL
  540.     );
  541.  
  542.     if (!gc)
  543.     return FALSE;
  544.  
  545.     XCopyGC (sysDisplay, GetGC(oldRP), (1L<<(GCLastBit+1))-1, gc);
  546.     SetGC (newRP, gc);
  547.  
  548.     return TRUE;
  549. }
  550.  
  551. void driver_DeinitRastPort (struct RastPort * rp, struct GfxBase * GfxBase)
  552. {
  553.     GC gc;
  554.  
  555.     if ((gc = GetGC (rp)))
  556.     {
  557.     XFreeGC (sysDisplay, gc);
  558.  
  559.     SetGC (rp, NULL);
  560.     }
  561. }
  562.  
  563.